package go_common

import (
	"strings"
	"unicode"
)

// ToCamelCase 将大写下划线分隔转换为小驼峰（camelCase）
func ToCamelCase(s string) string {
	// 如果字符串为空，直接返回
	if s == "" {
		return s
	}

	// 检查是否已经是驼峰格式（没有下划线且包含大小写混合）
	if !strings.Contains(s, "_") && isAlreadyCamelCase(s) {
		// 如果已经是小驼峰格式，直接返回
		if unicode.IsLower(rune(s[0])) {
			return s
		}
		// 如果是大驼峰格式，转换为小驼峰
		return strings.ToLower(s[:1]) + s[1:]
	}

	// 将字符串转为小写并按下划线分割
	parts := strings.Split(strings.ToLower(s), "_")

	// 如果只有一个部分，直接返回小写
	if len(parts) <= 1 {
		return strings.ToLower(s)
	}

	// 第一个单词保持小写，后续单词首字母大写
	result := parts[0]
	for i := 1; i < len(parts); i++ {
		if len(parts[i]) > 0 {
			result += strings.ToUpper(parts[i][:1]) + parts[i][1:]
		}
	}

	return result
}

// ToPascalCase 将大写下划线分隔转换为大驼峰（PascalCase）
func ToPascalCase(s string) string {
	// 如果字符串为空，直接返回
	if s == "" {
		return s
	}

	// 检查是否已经是驼峰格式（没有下划线且包含大小写混合）
	if !strings.Contains(s, "_") && isAlreadyCamelCase(s) {
		// 如果已经是大驼峰格式，直接返回
		if unicode.IsUpper(rune(s[0])) {
			return s
		}
		// 如果是小驼峰格式，转换为大驼峰
		return strings.ToUpper(s[:1]) + s[1:]
	}

	// 将字符串转为小写并按下划线分割
	parts := strings.Split(strings.ToLower(s), "_")

	var result string
	// 所有单词首字母都大写
	for _, part := range parts {
		if len(part) > 0 {
			result += strings.ToUpper(part[:1]) + part[1:]
		}
	}

	return result
}

// isAlreadyCamelCase 检查字符串是否已经是驼峰格式
func isAlreadyCamelCase(s string) bool {
	if len(s) == 0 {
		return false
	}

	// 检查是否包含大小写混合
	hasUpper := false
	hasLower := false

	for _, r := range s {
		if unicode.IsUpper(r) {
			hasUpper = true
		} else if unicode.IsLower(r) {
			hasLower = true
		}
		// 如果包含非字母字符（除了数字），则不是驼峰格式
		if !unicode.IsLetter(r) && !unicode.IsDigit(r) {
			return false
		}
	}

	// 驼峰格式应该同时包含大写和小写字母
	return hasUpper && hasLower
}
